package com.srs.backend.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.srs.backend.mapper.FoodMapper;
import com.srs.backend.mapper.OrderItemMapper;
import com.srs.backend.mapper.ReviewMapper;
import com.srs.backend.mapper.ServerMapper;
import com.srs.backend.pojo.*;
import com.srs.backend.service.ReviewService;
import com.srs.backend.utils.Result;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ReviewServiceImpl implements ReviewService {
    @Resource
    private ReviewMapper reviewMapper;
    @Resource
    private OrderItemMapper orderItemMapper;
    @Resource
    private ServerMapper serverMapper;
    @Resource
    private FoodMapper foodMapper;

    @Override
    public Result add(Map<String, String> data) {
       String orderItemIdStr = data.get("order_item_id");
       String serverIdStr = data.get("server_id");
       String foodIdStr = data.get("food_id");
       String starStr = data.get("star");
       String foodOrServerStr = data.get("food_or_server");
       String content = data.get("content");
       String remark = data.get("remark");

       Integer orderItemId=null;
       Integer serverId=null;
       Integer foodId=null;
       Integer star = null;
       Integer foodOrServer = null;

        try {
            orderItemId = Integer.parseInt(orderItemIdStr);
            serverId = Integer.parseInt(serverIdStr);
            foodId = Integer.parseInt(foodIdStr);
            star = Integer.parseInt(starStr);
            foodOrServer = Integer.parseInt(foodOrServerStr);
        } catch (NumberFormatException e) {
            return Result.error("菜品、服务员、订单、评分或类型选择 数据格式有误");
        }

        OrderItem curOrederItem = orderItemMapper.selectById(orderItemId);
        Server curServer = serverMapper.selectById(serverId);
        Food curFood = foodMapper.selectById(foodId);

        if (curServer == null) {
            return Result.error("服务员不存在或已被删除");
        }
        if (curOrederItem == null) {
            return Result.error("订单不存在或已被删除");
        }
        if (curFood == null) {
            return Result.error("菜品不存在或已被删除");
        }

        QueryWrapper<Review> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_item_id",orderItemId);
        queryWrapper.eq("server_id",serverId);
        queryWrapper.eq("food_id",foodId);

        List<Review> reviewList = reviewMapper.selectList(queryWrapper);
        if (!reviewList.isEmpty()) {
            return Result.error("当前 订单-服务员-菜品 关系已存在");
        }

        Integer foodOrServerValue = null;
        if (foodOrServer == 0) {
            foodOrServerValue = foodId;
        } else if (foodOrServer == 1) {
            foodOrServerValue = serverId;
        }

        reviewMapper.insert(new Review(null,orderItemId,null,serverId,foodId,foodOrServerValue,star.doubleValue(),content,remark));

        return Result.ok();
    }

    @Override
    public Result delete(Map<String, String> data){
        String idStr = data.get("id");
        Integer id = null;
        try {
            id = Integer.parseInt(idStr);
        } catch (NumberFormatException e) {
            return Result.error("id数据有误");
        }
        Review cur = reviewMapper.selectById(id);
        if (cur == null) {
            return Result.error("当前对应已被删除或不存在");
        }
        reviewMapper.deleteById(cur);
        return Result.ok("success");
    }

    @Override
    public Result modify(Map<String, String> data) {
        String idStr = data.get("id");
        Integer id = null;
        try {
            id = Integer.parseInt(idStr);
        } catch (NumberFormatException e) {
            return Result.error("id数据有误");
        }

        Review cur=reviewMapper.selectById(id);
        if (cur == null) {
            return Result.error("当前对应已被删除或不存在");
        }

        String orderItemIdStr = data.get("order_item_id");
        String serverIdStr = data.get("server_id");
        String foodIdStr = data.get("food_id");
        String starStr = data.get("star");
        String foodOrServerStr = data.get("food_or_server");
        String remark = data.get("remark");

        Integer orderItemId=null;
        Integer serverId=null;
        Integer foodId=null;
        Integer star = null;
        Integer foodOrServer = null;

        try {
            orderItemId = Integer.parseInt(orderItemIdStr);
            serverId = Integer.parseInt(serverIdStr);
            foodId = Integer.parseInt(foodIdStr);
            star = Integer.parseInt(starStr);
            foodOrServer = Integer.parseInt(foodOrServerStr);
        } catch (NumberFormatException e) {
            return Result.error("菜品、服务员、订单、评分或类型选择 数据格式有误");
        }

        OrderItem curOrederItem = orderItemMapper.selectById(orderItemId);
        Server curServer = serverMapper.selectById(serverId);
        Food curFood = foodMapper.selectById(foodId);

        if (curServer == null) {
            return Result.error("服务员不存在或已被删除");
        }
        if (curOrederItem == null) {
            return Result.error("订单不存在或已被删除");
        }
        if (curFood == null) {
            return Result.error("菜品不存在或已被删除");
        }

        QueryWrapper<Review> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_item_id",orderItemId);
        queryWrapper.eq("server_id",serverId);
        queryWrapper.eq("food_id",foodId);

        List<Review> reviewList = reviewMapper.selectList(queryWrapper);
        if (!reviewList.isEmpty()) {
            return Result.error("当前 订单-服务员-菜品 关系已存在");
        }


        Integer foodOrServerValue = null;
        if (foodOrServer == 0) {
            foodOrServerValue = foodId;
        } else if (foodOrServer == 1) {
            foodOrServerValue = serverId;
        }

        cur.setOrderItemId(orderItemId);
        cur.setFoodOrServer(foodOrServer);
        cur.setServerId(serverId);
        cur.setFoodId(foodId);
        cur.setStar(star.doubleValue());
        cur.setContent(cur.getContent());
        cur.setRemark(remark);

        // 这里需要更新数据库
        reviewMapper.updateById(cur);

        return Result.ok();
    }

    @Override
    public Result getAll() {
        return Result.ok(reviewMapper.selectList(null));
    }

    // 给菜品添加评论
    @Override
    public Result addReviewByFoodId(Map<String, String> data) {
//        System.out.println(data);
        String foodIdStr = data.get("food_id");
        Integer foodId;
        try {
            foodId = Integer.parseInt(foodIdStr);
        } catch (Exception e) {
            return Result.error("foodId数据类型有误");
        }
        Food food = foodMapper.selectById(foodId);
        if (food == null) {
            return Result.error("该菜品不存在或已被删除");
        }
        String orderItemIdStr = data.get("order_item_id");
        Integer orderItemId;
        try {
            orderItemId = Integer.parseInt(orderItemIdStr);
        } catch (Exception e) {
            return Result.error("orderItemId数据类型有误");
        }
        String starStr = data.get("star");
        String content = data.get("content");
        Double star;
        try {
            star = Double.parseDouble(starStr);
        } catch (Exception e) {
            return Result.error("star数据类型有误");
        }
        if (content.length() > 200) {
            return Result.error("评论内容过长");
        }
        reviewMapper.insert(new Review(null, orderItemId, null, null, foodId, 0, star, content, null));
        return Result.ok();
    }
    // 给服务员添加评论
    @Override
    public Result addReviewByServerId(Map<String, String> data) {
        String serverIdStr = data.get("server_id");
        Integer serverId;
        try {
            serverId = Integer.parseInt(serverIdStr);
        } catch (Exception e) {
            return Result.error("id数据类型有误");
        }
        Server server = serverMapper.selectById(serverId);
        if (server == null) {
            return Result.error("该服务员不存在或已被删除");
        }
        String orderIdStr = data.get("order_id");
        Integer orderId;
        try {
            orderId = Integer.parseInt(orderIdStr);
        } catch (Exception e) {
            return Result.error("orderId数据类型有误");
        }
        String starStr = data.get("star");
        String content = data.get("content");
        Double star;
        try {
            star = Double.parseDouble(starStr);
        } catch (Exception e) {
            return Result.error("star数据类型有误");
        }
        if (content.length() > 200) {
            return Result.error("评论内容过长");
        }
        reviewMapper.insert(new Review(null, null, orderId, serverId, null, 1, star, content, null));
        return Result.ok();
    }
    // 获取菜品评价排行榜
    @Override
    public Result getReviewRankAboutFood(Map<String, String> data) {
        String pageNumStr = data.get("page_num");
        String pageContentStr = data.get("page_content");
        Integer pageNum, pageContent;
        try {
            pageNum = Integer.parseInt(pageNumStr);
            pageContent = Integer.parseInt(pageContentStr);
        } catch (Exception e) {
            return Result.error("页码、页面大小数据类型有误");
        }
        if (pageNum < 0) {
            return Result.error("页码范围有误");
        }
        List<Food> foodList = foodMapper.selectList(null);
        for (int i = 0; i < foodList.size(); i ++ ) {
            Integer fid = foodList.get(i).getId();
            QueryWrapper<Review> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("food_or_server", 0);
            queryWrapper.eq("food_id", fid);
            List<Review> reviewList = reviewMapper.selectList(queryWrapper);
            Double star = this.getAverageStar(reviewList);
            foodList.get(i).setFoodReviewStar(star);
        }
        // 排序
        foodList.sort(new Comparator<Food>() {
            @Override
            public int compare(Food o1, Food o2) {
                return (int) Math.round(o2.getFoodReviewStar() - o1.getFoodReviewStar());
            }
        });
        // 分页
        List<Food> res;
        try {
            res = foodList.subList(pageNum * pageContent, Math.min(foodList.size(),(pageNum + 1) * pageContent - 1));
        } catch (Exception e) {
            return Result.error("分页数据有误");
        }
        return Result.ok(String.valueOf(foodList.size()), res);
    }
    // 获取服务评价排行榜
    @Override
    public Result getReviewRankAboutServer(Map<String, String> data) {
        String pageNumStr = data.get("page_num");
        String pageContentStr = data.get("page_content");
        Integer pageNum, pageContent;
        try {
            pageNum = Integer.parseInt(pageNumStr);
            pageContent = Integer.parseInt(pageContentStr);
        } catch (Exception e) {
            return Result.error("页码、页面大小数据类型有误");
        }
        if (pageNum < 0) {
            return Result.error("页码范围有误");
        }
        List<Server> serverList = serverMapper.selectList(null);
        for (int i = 0; i < serverList.size(); i ++ ) {
            Integer sid = serverList.get(i).getId();
            QueryWrapper<Review> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("food_or_server", 1);
            queryWrapper.eq("server_id", sid);
            List<Review> reviewList = reviewMapper.selectList(queryWrapper);
            Double star = this.getAverageStar(reviewList);
            serverList.get(i).setServerReviewStar(star);
        }
        // 排序
        serverList.sort(new Comparator<Server>() {
            @Override
            public int compare(Server o1, Server o2) {
                return (int) Math.round(o2.getServerReviewStar() - o1.getServerReviewStar());
            }
        });
        // 分页
        List<Server> res;
        try {
            res = serverList.subList(pageNum * pageContent, Math.min(serverList.size(),(pageNum + 1) * pageContent - 1));
        } catch (Exception e) {
            return Result.error("分页数据有误");
        }
        return Result.ok(String.valueOf(serverList.size()), res);
    }

    public Double getAverageStar(List<Review> reviewList) {
        Double res = 0.0;
        for (int i = 0; i < reviewList.size(); i ++ ) {
            res += reviewList.get(i).getStar();
        }
        return res / reviewList.size();
    }
}
